package com.stylefeng.guns.common.annotion.handle;

import com.alibaba.fastjson.JSON;
import com.stylefeng.guns.common.annotion.EmpCode;
import com.stylefeng.guns.common.annotion.Point;
import com.stylefeng.guns.common.annotion.PointType;
import com.stylefeng.guns.common.annotion.Year;
import com.stylefeng.guns.common.constant.Const;
import com.stylefeng.guns.common.constant.bean.PointTypePojo;
import com.stylefeng.guns.common.persistence.model.EmpPoints;
import com.stylefeng.guns.common.persistence.model.Employee;
import com.stylefeng.guns.core.util.NumUtil;
import com.stylefeng.guns.core.util.ReflectUtil;
import com.stylefeng.guns.modular.train.service.IContestPointsService;
import com.stylefeng.guns.modular.train.service.IEmpPointsService;
import com.stylefeng.guns.modular.train.service.IEmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author rockjh 【rockjh@aliyun.com】
 * @Description:
 * @Date 2018/1/31 16:41
 **/
@Component
public class PointComponent {

    @Autowired
    private IEmpPointsService empPointsService;

    @Autowired
    private IEmployeeService employeeService;


    /**
     * 积分注解处理器
     * @param newObj
     * @param oldObj
     * @param operation
     * @param <T>
     */
    public <T> void pointTypeHandle(T newObj,T oldObj,String operation){
        try {
            if(oldObj!=null && newObj!=null && newObj.getClass()!=oldObj.getClass()){
                return;
            }
            Object notNullInstance;
            if(newObj!=null){
                notNullInstance=newObj;
            }else {
                notNullInstance=oldObj;
            }
            boolean isPointEntity=notNullInstance.getClass().isAnnotationPresent(PointType.class);
            String pointType=notNullInstance.getClass().getAnnotation(PointType.class).value();
            if(!isPointEntity){
                return;
            }

            if(StringUtils.isEmpty(pointType)){
                return;
            }
            double oldIntegral=0;
            double newIntegral=0;
            double changeIntegral=0;
            String newYear="";
            String oldYear="";
            String empCode="";
            Field[] fields=notNullInstance.getClass().getDeclaredFields();
            for (Field field:fields){
                if(field.isAnnotationPresent(Point.class)){
                    if(Const.OPERATION_DELETE.equals(operation)) {
                        oldIntegral = NumUtil.objParseDouble(ReflectUtil.getValue(oldObj, field.getName()));
                        newIntegral=0;
                    }else if(Const.OPERATION_ADD.equals(operation)) {
                        newIntegral = NumUtil.objParseDouble(ReflectUtil.getValue(newObj, field.getName()));
                    }else if(Const.OPERATION_UPDATE.equals(operation)) {
                        newIntegral = NumUtil.objParseDouble(ReflectUtil.getValue(newObj, field.getName()));
                        if(oldObj!=null){
                            oldIntegral=NumUtil.objParseDouble(ReflectUtil.getValue(oldObj, field.getName()));
                        }
                    }
                }
                if(field.isAnnotationPresent(Year.class) ){
                    if(oldObj!=null && newObj!=null) {
                        oldYear = NumUtil.objParseString(ReflectUtil.getValue(oldObj, field.getName()));
                        newYear = NumUtil.objParseString(ReflectUtil.getValue(newObj, field.getName()));
                    }else {
                        if(newObj!=null) {
                            newYear = NumUtil.objParseString(ReflectUtil.getValue(newObj, field.getName()));
                            oldYear=newYear;
                        }
                        if(oldObj!=null) {
                            oldYear = NumUtil.objParseString(ReflectUtil.getValue(oldObj, field.getName()));
                            newYear=oldYear;
                        }
                    }
                }
                if(field.isAnnotationPresent(EmpCode.class)){
                    empCode=NumUtil.objParseString(ReflectUtil.getValue(notNullInstance,field.getName()));
                }
            }
            if(StringUtils.isEmpty(newYear) || StringUtils.isEmpty(empCode)){
                return;
            }
            if(oldObj!=null && !oldYear.equals(newYear)){
                changePoint(empCode,oldYear,pointType,-oldIntegral);
                changeIntegral=newIntegral;
            }else{
                changeIntegral=newIntegral-oldIntegral;
            }
            changePoint(empCode,newYear,pointType,changeIntegral);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 改变用户积分
     * @param empCode
     * @param year
     * @param changeIntegral
     * @param pointType
     * @return
     */
    private void changePoint(String empCode,String year,String pointType,double changeIntegral ){
        Map<String, Object> columnMap=new HashMap<>();
        columnMap.put("year",year);
        columnMap.put("emp_code",empCode);
        List<EmpPoints> empPointsList = empPointsService.selectByMap(columnMap);
        EmpPoints empPoints;
        if(empPointsList.size()==0){
            Map<String, Object> temp=new HashMap<>();
            temp=new HashMap<>();
            temp.put("emp_code",empCode);
            List<Employee> employees=employeeService.selectByMap(temp);
            if(employees.size()==0){
                return;
            }
            empPoints=empPointsService.createInstance(employees.get(0));
            empPoints.setYear(year);
            empPointsService.insert(empPoints);
        }else {
            empPoints = empPointsList.get(0);
        }
        empPoints.changeTotalPoint(changeIntegral);
        if(empPoints.getTotalPoint()<0){
            empPoints.setTotalPoint(0.0);
        }
        PointTypePojo pointTypePojo= JSON.parseObject(empPoints.getModularPonit(),PointTypePojo.class);
        pointTypePojo.change(pointType,changeIntegral);
        empPoints.setModularPonit(JSON.toJSONString(pointTypePojo));
        empPointsService.updateById(empPoints);
    }
}
